//#include"DisjointSet.h"
#include<iostream>
#ifndef DISJOINTSET
#define DISJOINTSET

#include<vector>

using std::vector;

template<typename T, typename point_T = T *>  //获得两个类型参数，一个是使用并查集的值类型，
class DisjointSet                            //另一个则是指向该类型的指针或迭代器
{
private:
	vector<point_T> point_array;
	vector<int> setNUM; //按0-N序号为传入的集合编号，并用于表示连通关系
	vector<int> size;  //表示对应序号所在任意连通结合集合的大小，包含多少元素
	int counts;

public:
	DisjointSet();
	DisjointSet(const point_T start, const point_T end); //使用超尾标记将集合元素到
	int findByCount(int i);   //按序号查询被查询节点所在集合的序号
	int findByVal(const T & val);  ///按值查询被查询节点所在集合的序号
	int  unionSet(int a, int b);   //合并两个集合
	void clear();
	void reset(const point_T start, const point_T end);
};


template<typename T, typename point_T>
DisjointSet<T, point_T>::DisjointSet()
{
	counts = 0;
}

template<typename T, typename point_T>
DisjointSet<T, point_T>::DisjointSet(point_T start, point_T end)
{
	counts = 0;
	while (start != end) {
		point_array.push_back(start++);
		setNUM.push_back(counts);
		counts++;
	}
	size.resize(counts, 1);
}

template<typename T, typename point_T>
int DisjointSet<T, point_T>::findByCount(int i)
{
	if (i > counts - 1) return -1;
	while (i != setNUM[i])
	{
		setNUM[i] = setNUM[setNUM[i]];
		i = setNUM[i];
	}
	return i;
}

template<typename T, typename point_T>
int DisjointSet<T, point_T>::findByVal(const T & val)
{
	int i = 0;
	for (i = 0; i<counts; i++)
	{
		if (*point_array[i] == val)
			break;
	}
	if (i<counts)
	{
		return findByCount(i);
	}
	else
		return -1;  //表示查找失败，不存在
}

template<typename T, typename point_T>
int DisjointSet<T, point_T>::unionSet(int a, int b)
{
	int	ua = findByCount(a);
	int ub = findByCount(b);
	if (ua == -1 || ub == -1) return -1;
	if (size[ua]>size[ub])
	{
		setNUM[ub] = ua;
		size[ua] = size[ua] + size[ub];
	}
	else
	{
		setNUM[ua] = ub;
		size[ub] = size[ua] + size[ub];
	}
}

template<typename T, typename point_T>
void DisjointSet<T, point_T>::clear()
{
	counts = 0;
	point_array.clear();
	setNUM.clear();
	size.clear();
}

template<typename T, typename point_T>
void DisjointSet<T, point_T>::reset(point_T start, point_T end)
{
	counts = 0;
	while (start != end) {
		point_array.push_back(start++);
		setNUM.push_back(counts);
		counts++;
	}
	size.resize(counts, 1);
}

#endif
#include<set>
using namespace std;

char arr[100000];
DisjointSet<char> join_set;

int main(void)
{
	bool q;
	int a,b;
	cin>>a>>b;
	set<int> s;
	while(a!=-1 || b!=-1)
	{
		join_set.reset(arr,arr+100000);
		q=true;
		while(a!=0 || b!=0)
		{
			s.insert(a);
			s.insert(b);
			if(join_set.findByCount(a-1)==join_set.findByCount(b-1) && (a!=b))
			{
				q=false;
			}
			if(a!=b)
				join_set.unionSet(a-1,b-1);
			cin>>a>>b;
		}
		if (s.size()>1)
		{
			a = join_set.findByCount(*s.begin()-1);
			for (set<int>::iterator i = ++s.begin(); i != s.end(); i++)
			{
				if (join_set.findByCount(*i-1) != a) q = false;
			}
		}
		if(q) cout<<"Yes"<<endl;
		else cout<<"No"<<endl;
		join_set.clear();
		s.clear();
		cin>>a>>b;
	}
	return 0;
} 
